package com.pll.service.Impl;

import com.pll.controller.Merchant.vo.MerchantAuthenticationVo;
import com.pll.dto.ResponseDto;
import com.pll.mapper.MerchantMapper;
import com.pll.pojo.Merchant;
import com.pll.pojo.MerchantCheck;
import com.pll.service.MerchantService;
import com.pll.util.AMapGeocoderUtil;
import com.pll.util.AliOSSUtil;
import com.pll.util.IdCheck2Util;
import com.pll.util.OcrUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.HashMap;
import java.util.Map;

@Slf4j
@RequiredArgsConstructor
@Service
public class MerchantServiceImpl implements MerchantService {

    private final MerchantMapper merchantMapper;
    private final AliOSSUtil aliOSSUtil;

    @Override
    public ResponseDto getMerchantStatus(String account) {
        try {
            //根据账号获取店铺的状态
            Merchant merchant = merchantMapper.getMerchantStatus(account);
            int certification = (int) merchant.getCertification();
            System.out.println("商家认证状态为："+certification);
            switch (certification) {
                case 1: {
                    //通过账号获取店铺id
                    Integer merchantId = merchantMapper.queryMerchantId(account);
                    //通过店铺id获取审核表信息
                    MerchantCheck check = merchantMapper.getCheckResult(merchantId);
                    System.out.println("审核状态为："+check.getCheckResult());
                    switch ((int) check.getCheckResult()) {
                        case 2:
                            System.out.println("审核不通过");
                            return ResponseDto.fail(401, check.getCheckNote());
                        default:
                            return ResponseDto.success(certification);
                    }
                }
                default:
                    log.info("获取商户状态成功，账号：{}，状态：{}", account, certification);
                    return ResponseDto.success(certification);
            }
        } catch (Exception e) {
            log.error("获取商户状态异常", e);
            return ResponseDto.fail(500, "系统异常");
        }
    }

    @Override
    public ResponseDto MerchantAuthentication(MerchantAuthenticationVo merchantAuthenticationVo) {
        // 处理营业执照OCR识别
        Map<String, String> businessLicenseResult = recognizeBusinessLicense(
                merchantAuthenticationVo.getBusinessLicenseUrl());
        if (businessLicenseResult == null) {
            return ResponseDto.fail(405, "营业执照识别失败，请上传清晰图片");
        }

        // 处理身份证OCR识别与验证
        Map<String, String> idCardResult = processIdCard(
                merchantAuthenticationVo.getIdCardFrontUrl());
        if (idCardResult == null) {
            return ResponseDto.fail(405, "身份证识别或验证失败，请上传清晰图片");
        }

        // 地址验证并获取经纬度
        String address = buildFullAddress(merchantAuthenticationVo);
        Map<String, String> geoResult = validateAndGetGeo(address);
        if (geoResult == null) {
            return ResponseDto.fail(405, "地址解析失败，请输入正确地址");
        }
        String longitude = geoResult.get("longitude");  // 经度
        String latitude = geoResult.get("latitude");      // 纬度
        String formattedAddress = geoResult.get("formattedAddress"); // 格式化地址

        // 所有验证通过后，上传图片到OSS
        Map<String, String> ossUrls = uploadImagesToOSS(
                merchantAuthenticationVo.getBusinessLicenseUrl(),
                merchantAuthenticationVo.getIdCardFrontUrl());
        if (ossUrls == null || ossUrls.isEmpty()) {
            return ResponseDto.fail(405, "图片上传OSS失败，请稍后重试");
        }

        // 组装数据并保存（包含经纬度）
        Map<String, Object> merchantData = assembleMerchantData(
                businessLicenseResult, idCardResult, address,
                merchantAuthenticationVo, ossUrls, longitude, latitude, formattedAddress);
        try {

            if (merchantMapper.merchantAuthentication(merchantAuthenticationVo, merchantData)>0){
                Integer merchantId = merchantMapper.queryMerchantId(merchantAuthenticationVo.getAccount());
                //判断店铺是否是二次提交的申请(被驳回的审核会二次提交申请)
                if (merchantMapper.getCheckExist(merchantId) !=null && merchantMapper.getCheckExist(merchantId)>0){
                    //是二次申请就会执行修改操作 将审核重新改为待审核为0
                    return ResponseDto.success(merchantMapper.updateCheckResult(merchantId));
                }
                if (merchantMapper.addCheck(merchantId)>0){
                    log.info("商户认证提交成功，商户号：{}", merchantAuthenticationVo.getAccount());
                    return ResponseDto.success(merchantId);
                }
            }
            return ResponseDto.fail(405,"认证提交失败");
        } catch (Exception e) {
            log.error("保存商户认证信息异常", e);
            return ResponseDto.fail(500, "系统异常，保存失败");
        }
    }

    /**
     * 营业执照OCR识别
     */
    private Map<String, String> recognizeBusinessLicense(MultipartFile file) {
        // 原有逻辑不变
        if (file == null || file.isEmpty()) {
            log.warn("未获取到营业执照图片");
            return null;
        }

        try {
            Map<String, String> ocrResult = OcrUtil.recognizeBusinessLicense(
                    file.getInputStream());

            if (ocrResult == null || ocrResult.isEmpty()
                    || ocrResult.get("regNum") == null || ocrResult.get("person") == null) {
                log.warn("营业执照OCR识别结果不完整：{}", ocrResult);
                return null;
            }

            log.info("营业执照识别成功，注册号：{}，法人：{}",
                    ocrResult.get("regNum"), ocrResult.get("person"));
            return ocrResult;
        } catch (IOException e) {
            log.error("营业执照OCR识别异常", e);
            return null;
        }
    }

    /**
     * 处理身份证识别与验证
     */
    private Map<String, String> processIdCard(MultipartFile file) {
        // 原有逻辑不变
        if (file == null || file.isEmpty()) {
            log.warn("未获取到身份证图片");
            return null;
        }

        try {
            Map<String, Object> idCardResponse = handleIdCardUpload(file);
            if (idCardResponse == null) {
                log.warn("身份证处理返回null");
                return null;
            }

            String status = (String) idCardResponse.get("status");
            if (!"success".equals(status)) {
                log.warn("身份证处理失败：{}", idCardResponse.get("message"));
                return null;
            }

            Map<String, String> result = new HashMap<>();
            result.put("name", (String) idCardResponse.get("name"));
            result.put("idNumber", (String) idCardResponse.get("idNumber"));
            result.put("idCheckStatus", (String) idCardResponse.get("idCheckStatus"));

            log.info("身份证处理成功，姓名：{}，身份证号：{}，验证状态：{}",
                    result.get("name"), result.get("idNumber"), result.get("idCheckStatus"));
            return result;
        } catch (Exception e) {
            log.error("身份证处理异常", e);
            return null;
        }
    }

    /**
     * 验证地址并获取经纬度
     */
    private Map<String, String> validateAndGetGeo(String address) {
        try {
            // 调用地址解析工具（使用新的standardAddress方法）
            Map<String, String> geoResult = AMapGeocoderUtil.standardAddress(address);
            if (geoResult == null) {
                log.warn("地址解析失败，地址：{}", address);
                return null;
            }

            // 直接从结果中获取经纬度（无需二次解析）
            String longitude = geoResult.get("longitude");
            String latitude = geoResult.get("latitude");

            // 验证经纬度是否存在
            if (longitude == null || latitude == null) {
                log.warn("地址解析结果缺少经纬度信息，地址：{}", address);
                return null;
            }

            log.info("地址解析成功，地址：{}，经纬度：{}，{}",
                    geoResult.get("formattedAddress"), longitude, latitude);
            return geoResult;
        } catch (Exception e) {
            log.error("地址解析异常，地址：{}", address, e);
            return null;
        }
    }

    /**
     * OCR验证通过后，上传图片到OSS
     */
    private Map<String, String> uploadImagesToOSS(MultipartFile businessLicenseFile,
                                                  MultipartFile idCardFile) {
        // 原有逻辑不变
        Map<String, String> ossUrls = new HashMap<>();

        try {
            if (businessLicenseFile != null && !businessLicenseFile.isEmpty()) {
                String ossUrl = aliOSSUtil.uploadFile(businessLicenseFile);
                if (ossUrl != null) {
                    ossUrls.put("businessLicenseUrl", ossUrl);
                }
            }

            if (idCardFile != null && !idCardFile.isEmpty()) {
                String ossUrl = aliOSSUtil.uploadFile(idCardFile);
                if (ossUrl != null) {
                    ossUrls.put("idCardFrontUrl", ossUrl);
                }
            }

            if (ossUrls.isEmpty()) {
                log.warn("图片上传OSS失败，所有图片上传均未成功");
                return null;
            }

            log.info("图片上传OSS成功，营业执照：{}，身份证：{}",
                    ossUrls.get("businessLicenseUrl"), ossUrls.get("idCardFrontUrl"));
            return ossUrls;
        } catch (Exception e) {
            log.error("图片上传OSS异常", e);
            return null;
        }
    }

    /**
     * 构建拼接地址
     */
    private String buildFullAddress(MerchantAuthenticationVo vo) {
        return vo.getRegion().getProvince() +
                vo.getRegion().getCity() +
                vo.getRegion().getDistrict() +
                vo.getAddress();
    }

    /**
     * 构建数据（包含经纬度）
     */
    private Map<String, Object> assembleMerchantData(
            Map<String, String> businessLicenseResult,
            Map<String, String> idCardResult,
            String address,
            MerchantAuthenticationVo vo,
            Map<String, String> ossUrls,
            String longitude, String latitude, String formattedAddress) {

        Map<String, Object> data = new HashMap<>();
        data.put("regNum", businessLicenseResult.get("regNum"));
        data.put("person", businessLicenseResult.get("person"));
        data.put("name", idCardResult.get("name"));
        data.put("idNumber", idCardResult.get("idNumber"));
        data.put("address", address);
        data.put("formattedAddress", formattedAddress); // 格式化地址
        data.put("longitude", longitude);               // 经度
        data.put("latitude", latitude);                 // 纬度
        data.put("account", vo.getAccount());

        String openTimeStr = vo.getOpenTime();
        String closeTimeStr = vo.getCloseTime();

        // 格式化营业时间
        String formattedBusinessHours = BusinessHoursFormatter.formatBusinessHours(openTimeStr, closeTimeStr);

        // 输出结果
        System.out.println("商户营业时间: " + formattedBusinessHours);
        data.put("businessTime",formattedBusinessHours);
        // 添加OSS存储路径
        data.put("businessLicenseOssUrl", ossUrls.get("businessLicenseUrl"));
        data.put("idCardFrontOssUrl", ossUrls.get("idCardFrontUrl"));
        return data;
    }

    public class BusinessHoursFormatter {

        /**
         * 格式化营业时间，显示为"HH:mm-HH:mm"格式
         * @param openTimeStr 营业时间字符串，格式为"yyyy-MM-dd HH:mm:ss"
         * @param closeTimeStr 关门时间字符串，格式为"yyyy-MM-dd HH:mm:ss"
         * @return 格式化后的营业时间字符串
         */
        public static String formatBusinessHours(String openTimeStr, String closeTimeStr) {
            try {
                // 定义日期时间格式
                DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

                // 从字符串中解析日期时间
                LocalTime openTime = LocalTime.parse(openTimeStr, formatter);
                LocalTime closeTime = LocalTime.parse(closeTimeStr, formatter);

                // 定义时间显示格式
                DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("HH:mm");

                // 格式化时间并连接
                return openTime.format(timeFormatter) + "-" + closeTime.format(timeFormatter);
            } catch (Exception e) {
                // 处理异常情况
                return "营业时间格式错误: " + e.getMessage();
            }
        }

        // 示例用法
        public static void main(String[] args) {
            String openTime = "2025-06-19 09:00:00";
            String closeTime = "2025-06-19 18:30:00";

            String formattedHours = formatBusinessHours(openTime, closeTime);
            System.out.println("营业时间: " + formattedHours);
        }
    }

    // 身份证二要素验证
    public Map<String, Object> handleIdCardUpload(MultipartFile file) {
        // 原有逻辑不变
        Map<String, Object> response = new HashMap<>();
        Map<String, String> ocrResult = null;

        try {
            if (file.isEmpty()) {
                response.put("status", "error");
                response.put("message", "身份证图片不能为空");
                log.warn("身份证图片为空");
                return response;
            }

            byte[] fileBytes = file.getBytes();
            ocrResult = OcrUtil.idCardRecognition(new java.io.ByteArrayInputStream(fileBytes));

            if (ocrResult == null || ocrResult.containsKey("error")) {
                response.put("status", "error");
                response.put("message", ocrResult != null ?
                        ocrResult.get("error") : "身份证识别服务无返回");
                log.warn("身份证OCR识别失败：{}", response.get("message"));
                return response;
            }

            response.put("status", "success");
            response.putAll(ocrResult);

            try {
                IdCheck2Util idCheck2Util = new IdCheck2Util();
                String idcheck = idCheck2Util.idcheck(
                        ocrResult.get("name"),
                        ocrResult.get("idNumber")
                );

                response.put("idCheckStatus", idcheck);
                if (!"身份认证成功".equals(idcheck)) {
                    response.put("status", "error");
                    response.put("message", "身份证二要素验证失败: " + idcheck);
                    log.warn("身份证二要素验证失败：{}，姓名：{}，身份证号：{}",
                            idcheck, ocrResult.get("name"), ocrResult.get("idNumber"));
                } else {
                    log.info("身份证二要素验证成功，姓名：{}，身份证号：{}",
                            ocrResult.get("name"), ocrResult.get("idNumber"));
                }
            } catch (Exception e) {
                response.put("status", "error");
                response.put("message", "身份证验证服务异常: " + e.getMessage());
                log.error("身份证验证异常", e);
            }

        } catch (IOException e) {
            response.put("status", "error");
            response.put("message", "身份证图片处理失败: " + e.getMessage());
            log.error("身份证图片处理异常", e);
        } catch (Exception e) {
            response.put("status", "error");
            response.put("message", "身份证处理系统异常: " + e.getClass().getSimpleName());
            log.error("身份证处理异常", e);
        }

        return response;
    }
}